package org.szy.core.common.uilts;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentParser;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Note;
import org.noear.solon.core.NvMap;
import org.noear.solon.core.handle.Context;
import org.szy.core.common.exception.BaseException;

/**
 * HttpServlet工具类，获取当前request和response
 *
 * @author wangbuhao
 * @date 2022-08-19
 * @since 1.0.0
 **/
public class ReqUtil {


    /**
     * 获取Web上下文
     *
     * @return Web上下文
     */
    public static Context getContext() {
        Context context;
        try {
            context = Context.current();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException("非Web上下文无法获取Request");
        }
        if (context == null) {
            throw new BaseException("非Web上下文无法获取Request");
        } else {
            return context;
        }
    }

    /**
     * 将 请求值转换为 map
     *
     * @return 请求值转换为 map
     */
    public static NvMap getParamMap() {
        // 参数Map
        Context ctx = getContext();
        return ctx.paramMap();
    }

    /**
     * 获取String 参数
     */
    @Note("获取String参数")
    public static String getStr(String key) {
        return getStr(key, null);
    }

    public static String getStr(String key, String def) {
        Context ctx = getContext();
        return ctx.paramOrDefault(key, def);
    }

    @Note("获取Integer参数")
    public static Integer getInt(String key) {
        return getInt(key, null);
    }

    @Note("获取Integer参数")
    public static Integer getInt(String key, Integer def) {
        Context ctx = getContext();
        return ctx.paramAsInt(key, def);
    }

    @Note("获取Long参数")
    public static Long getLong(String key) {
        return getLong(key, null);
    }

    public static Long getLong(String key, Long def) {
        Context ctx = getContext();
        return ctx.paramAsLong(key, def);
    }

    /**
     * 判断是否是 ajax 请求
     */
    public static boolean isAjax(Context ctx) {
        if (ctx == null) ctx = Context.current();
        String accept = ctx.header("accept");
        if (accept != null && accept.contains("application/json")) {
            return true;
        }
        String xRequestedWith = ctx.header("X-Requested-With");
        if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
            return true;
        }
        String url = ctx.url();
        if (StrUtil.equalsAny(url, true, ".json", ".xml")) {
            return true;
        }
        String ajax = ctx.param("__ajax");
        return StrUtil.equalsAny(ajax, true, "json", "xml");
    }


    /**
     * 内容编码
     *
     * @param str 内容
     * @return 编码后的内容
     */
    public static String urlEncode(String str) {
        return URLUtil.encode(str, CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * 内容解码
     *
     * @param str 内容
     * @return 解码后的内容
     */
    public static String urlDecode(String str) {
        return URLUtil.decode(str, CharsetUtil.CHARSET_UTF_8);
    }


    public static String getBaseUrl() {
        Context ctx = Context.current();
        return ctx == null ? null : getBaseUrl(ctx);
    }

    public static String getBaseUrl(Context ctx) {
        int port = Solon.cfg().serverPort();
        return StrUtil.builder(128).append(port == 443 ? "https://" : "http://")
                .append(Solon.cfg().serverHost())
                .append(port == 80 || port == 443 ? "" : ":" + port)
                .append(ContextPathUtil.getContextPath()).toString();
    }

    public static String getCurrentUrl(Context ctx) {
        String queryString = ctx.queryString();
        String url = getBaseUrl(ctx) + ctx.path();
        if (StrUtil.isNotBlank(queryString)) {
            url = url.concat("?").concat(queryString);
        }
        return url;
    }

    public static String getReferer(Context ctx) {
        return ctx.header("Referer");
    }

    public static String getUserAgentStr(Context ctx) {
        return ctx.header("User-Agent");
    }

    public static UserAgent getUserAgent(Context ctx) {
        return UserAgentParser.parse(getUserAgentStr(ctx));
    }

    /**
     * 是否是IE浏览器
     */
    public static boolean isIEBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        if (StrUtil.isBlank(ua)) {
            return false;
        }

        ua = ua.toLowerCase();
        if (ua.contains("msie")) {
            return true;
        }

        return ua.contains("gecko") && ua.contains("rv:11");
    }

    /**
     * 是否是微信浏览器
     */
    public static boolean isWechatBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        return StrUtil.isNotBlank(ua) && ua.toLowerCase().contains("micromessenger");
    }

    /**
     * 是否是PC版的微信浏览器
     */
    public static boolean isWechatPcBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        return StrUtil.isNotBlank(ua) && ua.toLowerCase().contains("windowswechat");
    }


}
